home *** CD-ROM | disk | FTP | other *** search
- // MSASSubroutines.c
- //
- // Original version by Jon Lansdell and Nigel Humphreys.
- // 4.0 and 3.1 updates by Greg Sutton.
- // Human Interface changes and GX Printing by Don Swatman
- // ©Apple Computer Inc 1996, all rights reserved.
-
- #include "MSASSubroutines.h"
-
- #include <AppleScript.h>
- #include <Resources.h>
- #include <AERegistry.h>
- #include <ASRegistry.h>
- #include <TextUtils.h>
-
- #ifdef THINK_C
- #include "PLStrs.h"
- #else
- #include <PLStringFuncs.h>
- #endif
-
- #include "MSAppleEvents.h"
- #include "MSAEUtils.h"
- #include "MSGlobals.h"
- #include "MSWindow.h"
-
-
- const short kSEScriptID = 128;
-
- extern ComponentInstance gScriptingComponent;
-
- #ifdef THINK_C
- extern pascal StringPtr PLstrcpy(StringPtr str1, StringPtr str2);
- extern pascal StringPtr PLstrcat(StringPtr str1, StringPtr str2);
- #endif
-
- AEIdleUPP gAEIdleUPP;
-
- OSAID gScript1ID;
- OSAID gScript2ID;
- // Script 3 targets a script application - its script is not loaded
- OSAID gScript4ID;
- OSAID gScript5ID;
-
- // Variables to target script application
- ProcessSerialNumber gScriptAppPSN;
- AEDesc gScriptAppAddress;
-
- Str31 gScript1Name = "\pscript shift";
- Str31 gScript2Name = "\pscript datestring";
- Str31 gScript3Name = "\pscript topseeturvee";
- Str31 gScript4Name = "\pscript changecreator";
- Str31 gScript5Name = "\pscript get/set selection";
-
-
- // Launch an application into the background given an FSSpec
-
- OSErr FSSpecLaunchApplication(const FSSpec *fileSpec, ProcessSerialNumber *PSN)
- {
- LaunchParamBlockRec launchRec;
- OSErr err;
-
- launchRec.launchBlockID = extendedBlock;
- launchRec.launchEPBLength = extendedBlockLen;
- launchRec.launchFileFlags = 0;
- launchRec.launchControlFlags = launchContinue + launchNoFileFlags + launchDontSwitch;
- launchRec.launchAppSpec = (FSSpecPtr)fileSpec;
- launchRec.launchAppParameters = nil;
-
- err = LaunchApplication(&launchRec);
-
- if (err == noErr)
- *PSN = launchRec.launchProcessSN;
-
- return(err);
- }
-
- // Set up the scripts we can send AppleEvents to them.
- // Launch the script application.
-
- void SetUpScripts( void )
- {
- FSSpec aSpec;
- OSErr err;
-
- aSpec.vRefNum = gAppRec.theSpec.vRefNum;
- aSpec.parID = gAppRec.theSpec.parID;
-
- gAEIdleUPP = NewAEIdleProc(IdleProc); // Universal Procedure - only used in here
-
- PLstrcpy( aSpec.name, gScript1Name );
- (void)LoadScriptFromResFile( &aSpec, kSEScriptID, &gScript1ID );
-
- PLstrcpy( aSpec.name, gScript2Name );
- (void)LoadScriptFromResFile( &aSpec, kSEScriptID, &gScript2ID );
-
- PLstrcpy( aSpec.name, gScript3Name );
- err = FSSpecLaunchApplication( &aSpec, &gScriptAppPSN );
- if (err == noErr)
- AECreateDesc( typeProcessSerialNumber,(Ptr)&gScriptAppPSN,
- sizeof( ProcessSerialNumber ), &gScriptAppAddress );
- else
- gScriptAppAddress.dataHandle = NULL;
-
- PLstrcpy( aSpec.name, gScript4Name );
- (void)LoadScriptFromResFile( &aSpec, kSEScriptID, &gScript4ID );
-
- PLstrcpy( aSpec.name, gScript5Name );
- (void)LoadScriptFromResFile( &aSpec, kSEScriptID, &gScript5ID );
-
- }
-
- // Given a FileSpec open the resource fork and Load the script resource of resID.
- // The resource file will be closed afterwards.
-
- OSErr LoadScriptFromResFile( FSSpec *theSpec, short theResID, OSAID *theScriptID )
- {
- short aFileRef;
- OSErr err;
-
- *theScriptID = kOSANullScript;
-
- aFileRef = FSpOpenResFile( theSpec, fsRdPerm );
- err = ResError( );
-
-
- if ( noErr == err && aFileRef > 0 )
- {
- err = LoadScriptFromResFileRef( aFileRef, theResID, theScriptID );
-
- CloseResFile( aFileRef );
- }
-
- return err;
- }
-
- // Given a file reference number for a resource file, and a resource ID
- // for a 'scpt' resource, this routine loads the already compiled script
- // and sets theScriptID to the components reference for it.
-
- OSErr LoadScriptFromResFileRef( short theRefNum, short theResID, OSAID *theScriptID )
- {
- short saveRefNum = CurResFile(); // save current resource
- AEDesc aScriptDesc = { typeNull, NULL };
- Handle aHandle;
- OSErr err;
-
- *theScriptID = kOSANullScript; // NULL before we do anything
-
- if ( ! theRefNum )
- return errAENoSuchObject;
-
- UseResFile( theRefNum ); // set this resource to be current
-
- aHandle = (Handle)Get1Resource( kOSAScriptResourceType, theResID );
- err = ResError( );
- if ( noErr != err ) goto done;
-
- HLock(aHandle);
- err = AECreateDesc( typeOSAGenericStorage, (Ptr)*aHandle,
- GetHandleSize( aHandle ), &aScriptDesc );
- HUnlock(aHandle);
- if ( noErr != err ) goto done;
-
- err = OSALoad( gScriptingComponent, &aScriptDesc,
- kOSAModeNull, theScriptID );
-
- done:
- if ( aHandle )
- ReleaseResource( aHandle );
- UseResFile( saveRefNum ); // reset back to resource previously set
-
- (void)AEDisposeDesc( &aScriptDesc );
-
- return err;
- }
-
- // Store the scipt ID as a 'scpt' resource, in file given, with the ID given.
-
- OSErr StoreScriptToResFile(FSSpec *theSpec, short theResID, OSAID theScriptID, StringPtr theResName )
- {
- short aFileRef;
- OSErr err;
-
- if ( theScriptID == kOSANullScript )
- return errAENoSuchObject;
-
- aFileRef = FSpOpenResFile( theSpec, fsWrPerm );
- err = ResError( );
-
- if ( noErr == err && aFileRef > 0 )
- {
- err = StoreScriptToResFileRef( aFileRef, theResID, theScriptID, theResName );
-
- CloseResFile( aFileRef );
- }
-
- return err;
- }
-
-
- OSErr StoreScriptToResFileRef( short theFileRef, short theResID, OSAID theScriptID, StringPtr theResName )
- {
- short saveRefNum = CurResFile(); // save current resource file
- AEDesc scriptData = { typeNull,NULL };
- Handle aHandle;
- OSErr err;
-
- if ( kOSANullScript == theScriptID )
- return noErr; // No script to store so that's okay
-
- if ( ! theFileRef )
- return fnfErr;
-
- UseResFile( theFileRef ); // set this resource to be current
-
- err = (OSErr)OSAStore( gScriptingComponent, theScriptID,
- typeOSAGenericStorage, kOSAModeNull, &scriptData );
- if ( noErr != err ) goto done;
-
- // Write over current script
- aHandle = Get1Resource( kOSAScriptResourceType, theResID );
- if ( aHandle )
- {
- RemoveResource( aHandle ); // Disposed of in current resource file
- err = ResError( );
- if ( noErr != err ) goto done;
- }
-
- aHandle = scriptData.dataHandle;
- HLock( aHandle );
- HandToHand( &aHandle );
- AddResource( aHandle, typeOSAGenericStorage, theResID, theResName );
- HUnlock( aHandle );
- err = ResError( );
-
- done:
- UpdateResFile( saveRefNum );
-
- (void)AEDisposeDesc( &scriptData );
-
- return err;
- }
-
- // Quit the script application, store changes to scripts and dispose of scripts.
-
- OSErr CleanUpAEScripts(void)
- {
- AppleEvent myAppleEvent = {typeNull,NULL},
- ignoreReply = {typeNull,NULL};
- FSSpec fileSpec;
- OSErr err;
-
- // Quit the script application we launched
- if (gScriptAppAddress.dataHandle)
- {
- err = AECreateAppleEvent(kCoreEventClass, kAEQuitApplication, &gScriptAppAddress,
- 0, 0, &myAppleEvent);
-
- if (err == noErr)
- err = AESend(&myAppleEvent, &ignoreReply, kAENoReply + kAEAlwaysInteract,
- kAENormalPriority, kAEDefaultTimeout, NULL, NULL);
-
- AEDisposeDesc(&myAppleEvent);
- }
-
- // Store the scripts used - this saves any changed properties and aliases
- fileSpec.vRefNum = gAppRec.theSpec.vRefNum;
- fileSpec.parID = gAppRec.theSpec.parID;
-
- PLstrcpy( fileSpec.name, gScript1Name );
- StoreScriptToResFile( &fileSpec, kSEScriptID, gScript1ID, gScript1Name );
-
- PLstrcpy( fileSpec.name, gScript2Name );
- StoreScriptToResFile( &fileSpec, kSEScriptID, gScript2ID, gScript2Name );
-
- PLstrcpy( fileSpec.name, gScript4Name );
- StoreScriptToResFile( &fileSpec, kSEScriptID, gScript4ID, gScript4Name );
-
- PLstrcpy( fileSpec.name, gScript5Name );
- StoreScriptToResFile( &fileSpec, kSEScriptID, gScript5ID, gScript5Name );
-
- (void)OSADispose( gScriptingComponent, gScript1ID );
- (void)OSADispose( gScriptingComponent, gScript2ID );
- (void)OSADispose( gScriptingComponent, gScript4ID );
- (void)OSADispose( gScriptingComponent, gScript5ID );
-
- return(err);
- }
-
-
- // Calls a script subroutine that takes two window names or numbers.
- // If a window doesn't exist then it is created, one window is then
- // moved below the other.
- // Uses predefined label parameters.
- // on shift around winMove below winStay
-
- OSErr ExecuteScript1(DPtr theDoc)
- {
- #ifdef __MWERKS__
- #pragma unused (theDoc)
- #endif
-
- AppleEvent myAppleEvent = {typeNull,NULL},
- ignoreReply = {typeNull,NULL};
- AEDesc selfAddress;
- OSErr myErr;
- Str255 handlerName = "\pshift",
- below = "\pBelow",
- above = "\pAbove";
-
- if (gScript1ID == kOSANullScript)
- return(noErr);
-
- myErr = MakeSelfAddress(&selfAddress);
- if (myErr != noErr) return noErr;
-
- // Set up a subroutine AppleEvent
- myErr = AECreateAppleEvent(kASAppleScriptSuite, kASSubroutineEvent, &selfAddress,
- kAutoGenerateReturnID, kAnyTransactionID, &myAppleEvent);
-
- // Add the name of the subroutine
- if (myErr == noErr)
- myErr = AEPutParamPtr(&myAppleEvent, keyASSubroutineName, typeChar,
- (Ptr)&handlerName[1], handlerName[0]);
-
- // Add the first predefined label parameter
- if (myErr == noErr)
- myErr = AEPutParamPtr(&myAppleEvent, keyASPrepositionAround, typeChar,
- (Ptr)&below[1], below[0]);
-
- // Add the second predefined label parameter
- if (myErr == noErr)
- myErr = AEPutParamPtr(&myAppleEvent, keyASPrepositionBelow, typeChar,
- (Ptr)&above[1], above[0]);
-
- if (myErr == noErr)
- myErr = OSADoEvent(gScriptingComponent, &myAppleEvent, gScript1ID,
- kOSAModeAlwaysInteract, &ignoreReply);
-
- (void)AEDisposeDesc( &selfAddress );
- (void)AEDisposeDesc( &myAppleEvent );
- (void)AEDisposeDesc( &ignoreReply );
-
- return(myErr);
- }
-
- // Calls a subroutine that returns the date and/or time depending
- // on parameters sent.
- // Uses subroutine defined label parameters.
- // on datestring given wDate:fDate, wTime:fTime
-
- OSErr ExecuteScript2(DPtr theDoc)
- {
- #ifdef __MWERKS__
- #pragma unused (theDoc)
- #endif
-
- AppleEvent myAppleEvent = {typeNull,NULL},
- myReply = {typeNull,NULL}; // Need to NULL for OSADoEvent() routine
- AEDesc selfAddress,
- textDesc;
- AEDescList paramList = {typeNull,NULL};
- OSErr myErr;
- Str255 pStr = "\pdatestring";
-
- if (gScript2ID == kOSANullScript)
- return(noErr);
-
- myErr = MakeSelfAddress(&selfAddress);
- if (myErr != noErr) return noErr;
-
- // Create an AppleScript subroutine AppleEvent
- myErr = AECreateAppleEvent(kASAppleScriptSuite, kASSubroutineEvent, &selfAddress,
- kAutoGenerateReturnID, kAnyTransactionID, &myAppleEvent);
-
- // Specify the routine by it's name
- if (myErr == noErr)
- myErr = AEPutParamPtr(&myAppleEvent, keyASSubroutineName, typeChar,
- (Ptr)&pStr[1], pStr[0]);
-
- // Create list for user defined label parameters
- if (myErr == noErr)
- myErr = AECreateList(NULL, 0 , false, ¶mList);
-
- if (myErr == noErr)
- { // Make sure label name is in lower case
- PLstrcpy(pStr,"\pwdate");
- myErr = AEPutPtr(¶mList, 0 ,typeChar ,(Ptr)&pStr[1], pStr[0]);
- if (myErr == noErr) myErr = AEPutPtr(¶mList, 0, typeTrue , NULL, 0);
- }
-
- if (myErr == noErr)
- {
- PLstrcpy(pStr,"\pwtime");
- myErr = AEPutPtr(¶mList, 0 ,typeChar ,(Ptr)&pStr[1], pStr[0]);
- if (myErr == noErr) AEPutPtr(¶mList, 0, typeFalse , NULL, 0);
- }
-
- // Add list to AppleEvent
- if (myErr == noErr)
- myErr = AEPutParamDesc(&myAppleEvent, keyASUserRecordFields, ¶mList);
-
- if (myErr == noErr)
- myErr = OSADoEvent(gScriptingComponent, &myAppleEvent, gScript2ID,
- kOSAModeAlwaysInteract, &myReply);
-
- AEDisposeDesc(&selfAddress);
- AEDisposeDesc(&myAppleEvent);
- AEDisposeDesc(¶mList);
-
- if (myErr == noErr)
- myErr = GetTextDescFromReply(&myReply, &textDesc);
-
- if (myErr == noErr)
- myErr = SetSelection(&textDesc);
-
- AEDisposeDesc(&textDesc);
- AEDisposeDesc(&myReply);
-
- return(myErr);
- }
-
- // First of all gets the current selection. Then calls a script application
- // subroutine to twist the text in the selection. Finally it sets the selection
- // with the result.
- // Uses a positional parameter.
- // on topseeturvee(someText)
-
- OSErr ExecuteScript3(DPtr theDoc)
- {
- #ifdef __MWERKS__
- #pragma unused (theDoc)
- #endif
-
- AppleEvent myAppleEvent = {typeNull,NULL},
- myReply = {typeNull,NULL};
- AEDescList paramList = {typeNull,NULL},
- textDesc;
- OSErr myErr;
- Str255 pStr = "\ptopseeturvee";
-
- if (! gScriptAppAddress.dataHandle)
- return(noErr);
-
- // Get the current selection of the front window
- myErr = GetSelection(&textDesc);
-
- // Create a subroutine AppleEvent
- if (myErr == noErr)
- myErr = AECreateAppleEvent(kASAppleScriptSuite, kASSubroutineEvent, &gScriptAppAddress,
- kAutoGenerateReturnID, kAnyTransactionID, &myAppleEvent);
-
- // Add the name of the subroutine
- if (myErr == noErr)
- myErr = AEPutParamPtr(&myAppleEvent, keyASSubroutineName, typeChar,
- (Ptr)&pStr[1], pStr[0]);
-
- // Create positional parameter list
- if (myErr == noErr)
- myErr = AECreateList(NULL, 0 ,false, ¶mList);
-
- // Add textDesc as positional parameter
- if (myErr == noErr)
- myErr = AEPutDesc(¶mList, 0, &textDesc);
-
- // Add positional parameter list
- if (myErr == noErr)
- myErr = AEPutParamDesc(&myAppleEvent, keyDirectObject, ¶mList);
-
- if (myErr == noErr)
- myErr = AESend(&myAppleEvent, &myReply, kAEWaitReply + kAEAlwaysInteract,
- kAENormalPriority, kAEDefaultTimeout, gAEIdleUPP, NULL);
-
- AEDisposeDesc(&myAppleEvent);
- AEDisposeDesc(¶mList);
- // Dispose of textDesc before we get one in reply
- AEDisposeDesc(&textDesc);
-
- if (myErr == noErr)
- myErr = GetTextDescFromReply(&myReply, &textDesc);
-
- if (myErr == noErr)
- {
- myErr = SetSelection(&textDesc);
- AEDisposeDesc(&textDesc);
- }
-
- AEDisposeDesc(&myReply);
-
- return(myErr);
- }
-
- // Calls script subroutine that changes a given file's creator
- // to the creator specified.
- // Uses direct and predefined label parameters.
- // on changecreator of aSpec into aCreator
-
- OSErr ExecuteScript4(DPtr theDoc)
- {
- AppleEvent myAppleEvent = {typeNull,NULL},
- ignoreReply = {typeNull,NULL};
- AEDesc selfAddress;
- AEDescList paramList = {typeNull,NULL};
- OSErr myErr;
- Str255 pStr = "\pchangecreator";
-
- if (gScript4ID == kOSANullScript)
- return(noErr);
-
- myErr = MakeSelfAddress(&selfAddress);
- if (myErr != noErr) return myErr;
-
- // Create a subroutine AppleEvent
- myErr = AECreateAppleEvent(kASAppleScriptSuite, kASSubroutineEvent, &selfAddress,
- kAutoGenerateReturnID, kAnyTransactionID, &myAppleEvent);
-
- // Add the name of the subroutine
- if (myErr == noErr)
- myErr = AEPutParamPtr(&myAppleEvent, keyASSubroutineName, typeChar,
- (Ptr)&pStr[1], pStr[0]);
-
- // Add the direct parameter
- if (myErr == noErr)
- myErr = AEPutParamPtr(&myAppleEvent, keyDirectObject, typeFSS,
- (Ptr)&(theDoc->theFSSpec), sizeof(FSSpec));
-
- // Add the subroutine parameter label
- if (myErr == noErr)
- {
- PLstrcpy(pStr, "\pToyS");
- myErr = AEPutParamPtr(&myAppleEvent, keyASPrepositionInto, typeChar,
- (Ptr)&pStr[1], pStr[0]);
- }
-
-
- if (myErr == noErr)
- myErr = OSADoEvent(gScriptingComponent, &myAppleEvent, gScript4ID,
- kOSAModeAlwaysInteract, &ignoreReply);
-
- AEDisposeDesc(&selfAddress);
- AEDisposeDesc(&myAppleEvent);
- AEDisposeDesc(&ignoreReply);
-
- return(myErr);
- }
-
-
- // Calls script subroutine to get this application's selection.
- // Uses no parameters except for subroutine name.
- // on getselection()
-
- OSErr GetSelection(AEDesc *textDesc)
- {
- AppleEvent myAppleEvent = {typeNull,NULL},
- myReply = {typeNull,NULL};
- AEDesc selfAddress;
- OSErr myErr;
- Str255 pStr = "\pgetselection";
-
- if (gScript5ID == kOSANullScript)
- return(noErr);
-
- myErr = MakeSelfAddress(&selfAddress);
- if (myErr != noErr) return myErr;
-
- // Create an AppleScript subroutine AppleEvent
- myErr = AECreateAppleEvent(kASAppleScriptSuite, kASSubroutineEvent, &selfAddress,
- kAutoGenerateReturnID, kAnyTransactionID, &myAppleEvent);
-
- // Specify the routine by it's name
- if (myErr == noErr)
- myErr = AEPutParamPtr(&myAppleEvent, keyASSubroutineName, typeChar,
- (Ptr)&pStr[1], pStr[0]);
-
- if (myErr == noErr)
- myErr = OSADoEvent(gScriptingComponent, &myAppleEvent, gScript5ID,
- kOSAModeAlwaysInteract, &myReply);
-
- myErr = GetTextDescFromReply(&myReply, textDesc);
-
- AEDisposeDesc(&selfAddress);
- AEDisposeDesc(&myAppleEvent);
- AEDisposeDesc(&myReply);
-
- return(myErr);
- }
-
-
- // Calls script subroutine to set this application's selection.
- // Uses a positional parameter.
- // setselection(aString)
-
- OSErr SetSelection(AEDesc *textDesc)
- {
- AppleEvent myAppleEvent = {typeNull,NULL},
- myReply = {typeNull,NULL};
- AEDesc selfAddress;
- AEDescList paramList = {typeNull,NULL};
- OSErr myErr;
- Str255 pStr = "\psetselection";
-
- if (gScript5ID == kOSANullScript)
- return(noErr);
-
- myErr = MakeSelfAddress(&selfAddress);
- if (myErr != noErr) return myErr;
-
- // Create an AppleScript subroutine AppleEvent
- myErr = AECreateAppleEvent(kASAppleScriptSuite, kASSubroutineEvent, &selfAddress,
- kAutoGenerateReturnID, kAnyTransactionID, &myAppleEvent);
-
- // Specify the routine by it's name
- if (myErr == noErr)
- myErr = AEPutParamPtr(&myAppleEvent, keyASSubroutineName, typeChar,
- (Ptr)&pStr[1], pStr[0]);
-
- // Create positional parameter list
- if (myErr == noErr)
- myErr = AECreateList(NULL, 0 ,false, ¶mList);
-
- // Add textDesc as positional parameter
- if (myErr == noErr)
- myErr = AEPutDesc(¶mList, 0, textDesc);
-
- // Add positional parameter list
- if (myErr == noErr)
- myErr = AEPutParamDesc(&myAppleEvent, keyDirectObject, ¶mList);
-
- if (myErr == noErr)
- myErr = OSADoEvent(gScriptingComponent, &myAppleEvent, gScript5ID,
- kOSAModeAlwaysInteract, &myReply);
-
- AEDisposeDesc(&selfAddress);
- AEDisposeDesc(&myAppleEvent);
- AEDisposeDesc(¶mList);
- AEDisposeDesc(&myReply);
-
- return(myErr);
- }
-
- // Takes a reply and tries to get a text descriptor from it.
-
- OSErr GetTextDescFromReply(AEDesc *aReply, AEDesc *textDesc)
- {
- OSErr myErr;
-
- textDesc->descriptorType = typeNull;
- textDesc->dataHandle = NULL;
-
- myErr = AEGetParamDesc(aReply, keyAEResult, typeChar, textDesc);
-
- return(myErr);
- }
-
-
- void EnableAEScriptItems(Boolean fEnable)
- {
- SetMenuItemState ( (fEnable && kOSANullScript != gScript1ID), myMenus[subroutineM], cScript1);
- SetMenuItemState ( (fEnable && kOSANullScript != gScript2ID), myMenus[subroutineM], cScript2);
- SetMenuItemState ( (fEnable && gScriptAppAddress.dataHandle), myMenus[subroutineM], cScript3);
- SetMenuItemState ( (fEnable && kOSANullScript != gScript4ID), myMenus[subroutineM], cScript4);
- }
-
- // IdleProc for AESend
- pascal Boolean IdleProc(EventRecord *myEvent, long *sleep, RgnHandle *mouseRgn)
- {
- WindowPtr theWindow;
- Boolean activate;
-
- switch ( myEvent->what )
- {
- case nullEvent:
- *sleep = 0; // no null processing in this sample
- mouseRgn = nil;
- break;
-
- case activateEvt:
- activate = ((myEvent->modifiers & activeFlag) != 0);
- theWindow = (WindowPtr)myEvent->message;
- DoActivate(theWindow, activate);
- break;
-
- case updateEvt:
- DoUpdate( (WindowPtr)myEvent->message );
- break;
-
- case osEvt:
- if ( ( myEvent->message >> 24 ) & suspendResumeMessage ) // suspend or resume
- {
- gInBackground = ((myEvent->message & resumeFlag) == 0);
- DoActivate(FrontWindow(), ! gInBackground);
- }
- break;
-
- default:
- SysBeep( 1 );
- break;
- }
-
- return false; // I'll wait forever
- }
-